import java.util.Scanner;
import lbtest.Person;
import lbtest.Student;

public class Main {
    public static void main(String[] args) {
        /** 父类测试 */
        Person t = new Person("----父类测试----");
        t.setName("王五");
        System.out.println(t.getName());
        System.out.println(t.getNum());
        t.hello("狗三");
        t.hello("狗四", 12);

        /** 继承测试 */
        // 向上转型 把一个子类类型安全地变为父类类型的赋值，被称为向上转型（upcasting）
        // 继承树是Student > Person > Object，所以，可以把Student类型转型为Person，或者更高层次的Object
        Person p2 = new Student("----向上转型----", 25);

        // 向下转型 把一个父类类型强制转型为子类类型，就是向下转型（downcasting）
        // 向下转型很可能会失败。失败的时候，Java虚拟机会报ClassCastException
        Person p1 = new Student("----向下转型----", 25); // upcasting, ok
        Person p3 = new Person("----向下转型----");
        Student s1 = (Student) p1; // ok
//        Student s3 = (Student) p3; // runtime error! ClassCastException! 不能把父类变为子类，因为子类功能比父类多，多的功能无法凭空变出来。

        /** instanceof */
        // 从Java 14开始，判断instanceof后，可以直接转型为指定变量，避免再次强制转型
        Person p4 = new Student("----instanceof----", 25); // upcasting, ok
        if (p4 instanceof Student) {
            Student s4 = (Student) p4;
            System.out.println(s4.getStdName());  // 必须强制转换类型为Student才可调用Student里面的方法 否则向上转型无法获取Student的方法
        }

        /** 多态测试 */
        Person p5 = new Student("----多态测试--------", 25);
        p5.mulFunc();  // 运行的是Student的mulFunc方法

        /** 接口测试 */
        p5.testInterface();  // 运行Person类的testInterface
        p5.testDefault();  // 运行接口的testDefault
    }

}